package com.funcourse.demo.api.websocket;

import com.funcourse.demo.business.RoomCacher;
import com.funcourse.demo.model.CompeteRoom;
import com.funcourse.demo.model.User;
import com.funcourse.demo.model.repo.UserRepo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import java.util.Map;
import org.springframework.web.util.UriComponentsBuilder;

@Slf4j
@Component
public class WebSocketHandShakeInterceptor extends HttpSessionHandshakeInterceptor {

    public static final String SESSION_ROOM ="competeRoom";
    public static final String SESSION_USER_ID ="userId";
    public static final String SESSION_IS_ORGANIZOR="isOrganizor";
    public static final String SESSION_TOP_USER_AMOUNT ="topUserAmount";

    @Autowired
    RoomCacher roomCacher;
    @Autowired
    UserRepo userRepo;

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        super.beforeHandshake(request,response,wsHandler,attributes);
        final MultiValueMap<String, String> queryParams = UriComponentsBuilder
            .fromHttpRequest(request).build().getQueryParams();
        String query = request.getURI().getQuery();
        log.debug("query got {}",query);
        final String userToken = queryParams.getFirst("token");
        final String roomId = queryParams.getFirst("roomId");
        final String isOrganizer = queryParams.getFirst("isOrganizer");

        if(null == userToken || null == roomId){
            log.error("connection not valid {}",query);
            return false;
        }
        final User connectionUser = userRepo.findByToken(userToken);
        if(null == connectionUser){
            log.error("no user found when socket connection for user {}",userToken);
            return false;
        }
        final CompeteRoom room = roomCacher.getRoomById(roomId);
        if(null == room){
            log.error("no room found when socket connection for room {}",roomId);
            return false;
        }
        attributes.put(SESSION_USER_ID, connectionUser.getId());
        attributes.put(SESSION_ROOM, room);
        attributes.put(SESSION_IS_ORGANIZOR, Boolean.valueOf(isOrganizer));
        final String topUserAmountStr = queryParams.getFirst("topUserAmount");
        Integer topUserAmount =5;
        if(!StringUtils.isEmpty(topUserAmountStr)){
            try{
                topUserAmount = Integer.parseInt(topUserAmountStr);
            }catch (Exception e){
                log.warn("parsing topUserAmount failed default is used");
            }
        }
        attributes.put(SESSION_TOP_USER_AMOUNT, topUserAmount);
        return true;
    }


}
